<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>PDF Viewer with Highlight</title>
    <link rel="stylesheet" href="./public/pdfjs/web/viewer.css" />
    <style>
        .ai-message {
            margin: 10px 0;
            padding: 8px 12px;
            border: 1px solid black;
            border-radius: 8px;
            background-color: #e0e0e0;
            text-align: left;
        }
        #pdf-viewer-container {
            width: 100%;
            height: 100vh;
            border: 1px solid #ccc;
            overflow: hidden;
        }
        .container {
            display: flex;
            height: 100vh;
        }
        .left-side {
            flex: 1;
            background-color: #f4f4f4;
            overflow-y: hidden;
            position: relative;
            height: 100%;
            border-right: 1px solid #000;
            border-radius: 8px 0 0 8px;
        }
        .right-side {
            flex: 1;
            display: flex;
            flex-direction: column;
            border-left: 1px solid #000;
            border-radius: 0 8px 8px 0;
        }
        .chat-window {
            flex: 1;
            overflow-y: auto;
            background-color: #fff;
            padding: 10px;
            border-bottom: 1px solid #000;
            border-radius: 8px 8px 0 0;
        }
        .input-area {
            display: flex;
            border-top: 1px solid #000;
            padding: 10px;
            background-color: #f4f4f4;
            border-radius: 0 0 8px 8px;
        }
        .message-input {
            flex-grow: 1;
            margin-right: 5px;
            border: 1px solid #000;
            border-radius: 4px;
            padding: 8px;
        }
        .send-button {
            padding: 5px 10px;
            cursor: pointer;
            border: 1px solid #000;
            border-radius: 4px;
            background-color: #fff;
        }
        .attachment-button {
            padding: 5px 10px;
            cursor: pointer;
            border: 1px solid #000;
            border-radius: 4px;
            background-color: #fff;
        }
        .text-div {
            border: 1px solid black;
            border-radius: 8px;
            margin: 10px 0;
            padding: 8px 12px;
            display: flex; /* 使用 Flexbox 布局 */
            flex-wrap: wrap; /* 允许容器内的项目换行 */
        }
        .text-p {
            font-size: 16px;
            color: rgb(0, 0, 0);
            padding-right: 20px; /* 为伪元素留出空间 */
            transition: font-weight 0.3s; /* 平滑过渡字体粗细变化 */
        }
        /*.text-p:not([data-length="0"]):hover {*/
        /*    font-weight: bold; !* 鼠标悬停时文本变粗 *!*/
        /*}*/
        .text-p:not([data-length="0"])::after {
            content: attr(data-status); /* 使用自定义属性作为内容 */
            position: relative;
            /*top: 50%;*/
            /*transform: translateY(-50%);*/
            display: inline-block;
            background-color: red;
            color: white;
            border-radius: 50%;
            padding: 1px 1px;
            font-size: 10px;
            min-width: 10px;
            text-align: center;
            height: 10px; /* 确保伪元素垂直居中 */
            line-height: 10px; /* 确保数字垂直居中 */
            transition: opacity 0.3s; /*平滑过渡显示隐藏*/
            /*opacity: 0; !*默认隐藏*!*/
        }
        /*.text-p:not([data-length="0"]):hover::after {*/
        /*    opacity: 1; !* 鼠标悬停时显示 *!*/
        /*}*/
        @keyframes thinkingAnimation {
          0%, 100% {
            content: "";
          }
          25% {
            content: " .";
          }
          50% {
            content: " . .";
          }
          75% {
            content: " . . .";
          }
        }
        @keyframes blink {
          0%, 100% {
            opacity: 1; /* 完全不透明 */
          }
          50% {
            opacity: 0.5; /* 半透明 */
          }
        }
        .thinking-dots {
            border: 1px solid black;
            border-radius: 8px;
            margin: 10px 0;
            padding: 8px 12px;
            animation: blink 2s linear infinite;
        }
        .thinking-dots::after {
            content: "";
            position: relative;
            top: 0;
            bottom: 0;
            animation: thinkingAnimation 1.5s steps(4) infinite, blink 2s linear infinite;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="left-side">
            <iframe id="pdf-viewer-container" width="100%" height="100%" src="./public/pdfjs/web/viewer.html"></iframe>
        </div>
        <div class="right-side">
            <div id="chatContent" class="chat-window"></div>
            <div class="input-area">
                <form id="uploadForm" enctype="multipart/form-data">
                    <input type="text" class="message-input" name="message" placeholder="输入消息...">
                    <button type="submit">发送消息</button>
                    <input type="file" name="files" id="pdfFile" accept=".txt, .pdf, .md, .xlsx, .xls, .docx, .doc" multiple />
                </form>
            </div>
        </div>
    </div>
    <script>
        var config;
        fetch("./config.json")
            .then(response => response.json())
            .then(data => {
                config = data;
            })
            .catch(error => {
                console.error("Error:", error);
            });

        function onclickAIMessage(p, coords_arr, length) {
            let coords = coords_arr;
            let len = length;
            let count = -1;
            return function() {
                count = (count + 1) % len;
                p.setAttribute('data-status', String(length - count - 1)); // 更新伪元素显示的数
                console.log("count: ", count, "len: ", len, "attr: ", len-count-1);
                sendHighlightMessage(coords[count]);
            };
        }

        function getFromData() {
            const formData = new FormData();
            const messageInput = document.querySelector(".message-input");
            const message = messageInput.value.trim();
            const fileInput = document.getElementById("pdfFile");
            const files = fileInput.files;

            if (message === "" && files.length === 0) {
                alert("消息和文件至少要有一个");
                return null;
            }

            if (message !== "") {
                formData.append("message", message);
            }

            if (files.length > 0) {
                for (let i = 0; i < files.length; i++) {
                    formData.append("files", files[i]);
                }
            }

            const pdfview = iframe.contentWindow.PDFViewerApplication;
            formData.append("current_page_n", pdfview.page);
            displayMessage(message, "user");
            return formData;
        }

        const iframe = document.getElementById("pdf-viewer-container");
        const chatContent = document.getElementById("chatContent");
        document.getElementById("uploadForm").addEventListener("submit", function(event) {
            event.preventDefault();
            const formData = getFromData();
            if (formData === null) {
                return;
            }
            let div = document.createElement('div');
            div.className = 'thinking-dots';
            div.innerHTML = '正在思考';
            div.id = 'thinking';
            chatContent.appendChild(div);

            fetch("http://" + config.LLMHost.host + ":" + config.LLMHost.port + "/upload-pdf", {
                method: "POST",
                body: formData,
            })
            .then((response) => {
                if (!response.ok) {
                    throw new Error("Network response was not ok: " + response.statusText);
                }
                return response.json();
            })
            .then((data) => {
                const new_pdf_src = "./public/pdfjs/web/viewer.html?file=http://" + config.LLMHost.host + ":" + config.LLMHost.port + data.file_path;
                let str = iframe.src;
                let startIndex = str.indexOf("file=") + "file=".length;
                let result = str.substring(startIndex);
                let url = "http://" + config.LLMHost.host + ":" + config.LLMHost.port + data.file_path;
                if (url !== decodeURIComponent(result)) {
                    iframe.src = new_pdf_src;
                }
                console.log(data);
                const textBlocks = data.block_info;
                div = document.getElementById("thinking");
                div.remove();

                displayAIMessage(create_p_BlockInfo(textBlocks));
                document.getElementById("uploadForm").reset();
            })
            .catch((error) => {
                console.error("Error:", error)
                div = document.getElementById("thinking");
                div.remove();
                displayErrorMessage(error)
            });
        });

        function create_p_BlockInfo(textBlocks){
            const pElements = [];
            textBlocks.forEach(item => {
                const p = document.createElement('p');
                p.textContent = item.text;
                p.className = 'text-p';
                p.setAttribute('data-length', String(item.coords.length)); // 设置可点击的次数
                if (item.coords.length > 0) {
                    p.style.cursor = 'pointer';
                    p.setAttribute('data-status', String(item.coords.length)); // 初始化状态为0
                    p.onclick = onclickAIMessage(p, item.coords, item.coords.length);
                }
                pElements.push(p);
            });
            return pElements
        }

        function displayErrorMessage(error) {
            let p = document.createElement('p')
            p.innerHTML = "发生错误："+error
            displayAIMessage([p])
        }

        function displayAIMessage(pElements) {
            const chatContent = document.getElementById("chatContent");
            const aiMessageDiv = document.createElement('div');
            aiMessageDiv.className = 'text-div ai-message';
            pElements.forEach(p => aiMessageDiv.appendChild(p));
            chatContent.appendChild(aiMessageDiv);
            chatContent.scrollTop = chatContent.scrollHeight;
        }

        function displayMessage(message, sender) {
            const chatContent = document.getElementById("chatContent");
            const div = document.createElement('div');
            div.className = 'text-div';
            div.textContent = message;
            if (sender === "ai") {
                div.style.textAlign = 'right';
            }
            chatContent.appendChild(div);
            chatContent.scrollTop = chatContent.scrollHeight;
        }

        function sendHighlightMessage(highlightCoordinates) {
            if (iframe.contentWindow) {
                console.log("定位的页码：", highlightCoordinates[0].pageNum, "顶部距离：", 1 - highlightCoordinates[0].top / 100 + 0.2);
                scrollToPagePosition(highlightCoordinates[0].pageNum, 1 - highlightCoordinates[0].top / 100 + 0.2);
                console.log("发送高亮消息");
                console.log(highlightCoordinates);
                iframe.contentWindow.postMessage(
                    { type: "highlight", coords: highlightCoordinates },
                    "*"
                );
            } else {
                console.log("Iframe未加载完成");
            }
        }

        async function scrollToPagePosition(pageNumber, percentage) {
            if (!iframe.contentWindow.PDFViewerApplication?.initialized) {
                console.error('PDF viewer 未初始化');
                return;
            }

            try {
                const page = await iframe.contentWindow.PDFViewerApplication.pdfDocument.getPage(pageNumber);
                const height = page.getViewport({ scale: 1 }).height;
                iframe.contentWindow.PDFViewerApplication.pdfViewer.scrollPageIntoView({
                    pageNumber: pageNumber,
                    destArray: [null, { name: 'XYZ' }, null, percentage * height]
                });
            } catch (error) {
                console.error('滚动失败:', error);
            }
        }
      </script>
    <script src="load_history.js"></script>
</body>
</html>